package com.onstar.cn.framework.mvp.base.core;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.transition.ChangeBounds;
import android.transition.Slide;
import android.view.Gravity;
import android.view.View;
import android.view.Window;

import com.onstar.cn.common.log.LogManager;
import com.onstar.cn.common.util.CommonUtil;
import com.onstar.cn.framework.R;
import com.onstar.cn.framework.utils.ViewInjectUtils;
import com.onstar.cn.map.OMapActivity;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @author 7828wc
 * @ClassName: BaseFragmentActivity
 * @Description: Fragment 基类
 * @date 2015年7月27日 下午2:29:41
 */
public abstract class BaseFragmentActivity extends OMapActivity {
    private LogManager log = LogManager.getInstance();
    protected List<Fragment> fragments = new ArrayList<Fragment>();
    private String currentFragmentTag = "";
    public String current_fragment = null;

    @Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        ViewInjectUtils.inject(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
//        log.d("current fragment activity is --->" + getClass().getSimpleName());
    }

    /**
     * @param @param  tag
     * @param @return 设定文件
     * @return BaseFragment 返回类型
     * @throws
     * @Title: getFragment
     * @Description: 根据Class.getSimpleName返回对应的Fragment
     */
    public BaseFragment getFragment(Class<? extends BaseFragment> clazz) {
        return this.getFragment(clazz.getSimpleName());
    }

    /**
     * @param @param  tag
     * @param @return 设定文件
     * @return BaseFragment 返回类型
     * @throws
     * @Title: getFragment
     * @Description: 根据TAG返回TAG对应的Fragment
     */
    public BaseFragment getFragment(String tag) {
        try {
            log.d("Get fragment by class<Fragment>.name:" + tag);
            return (BaseFragment) getFManager().findFragmentByTag(tag);
        } catch (Exception e) {
            e.printStackTrace();
            log.e("get fragment error", e);
            return null;
        }
    }

    /**
     * @param @return 设定文件
     * @return FragmentManager 返回类型
     * @throws
     * @Title: getFManager
     * @Description: Fragment manager
     */
    public FragmentManager getFManager() {
        return getSupportFragmentManager();
    }

    /**
     * @param @return 设定文件
     * @return String 返回类型
     * @throws
     * @Title: getCurrentFragmentTag
     * @Description: 返回当前Fagment tag
     */
    public String getCurrentFragmentTag() {
        return currentFragmentTag;
    }

    /**
     * @param @return 设定文件
     * @return String 返回类型
     * @throws
     * @Title: getCurrentFragmentTag
     * @Description: 设置Fagment tag
     */
    public void setCurrentFragmentTag(String currentFragmentTag) {
        this.currentFragmentTag = currentFragmentTag;
    }

    public void setCurrentFragment(String fragment) {
        this.current_fragment = fragment;
    }

    /**
     * @param @return 设定文件
     * @return Fragment 返回类型
     * @throws
     * @Title: getCurrentFragment
     * @Description: 返回当前Fagment
     */
    public Fragment getCurrentFragment(FragmentManager fragmentManager) {
        return fragmentManager.findFragmentById(R.id.fragment_container);
    }

    /**
     * @param @return 设定文件
     * @return LogManager 返回类型
     * @throws
     * @Title: getLogger
     * @Description: 日志管理器
     */
    public LogManager getLogger() {
        return log;
    }

    /**
     * @param @param fragmentManager
     * @param @param fragment
     * @param @param clazz
     * @param @param isAddBackStack 设定文件
     * @return void 返回类型
     * @throws
     * @Title: changeFragment
     * @Description: 切换Fragment
     */
    public void changeFragment(Fragment fragment, Class<?> clazz, boolean isAddBackStack) {
        String tag = clazz.getSimpleName();
        changeFragment(getFManager(), fragment, tag, isAddBackStack);
    }

    /**
     * @param @param fragmentManager
     * @param @param fragment
     * @param @param clazz
     * @param @param isAddBackStack 设定文件
     * @return void 返回类型
     * @throws
     * @Title: changeFragment
     * @Description: 切换Fragment
     */
    public void changeFragment(FragmentManager fragmentManager, Fragment fragment, Class<?> clazz,
                               boolean isAddBackStack) {
        String tag = clazz.getSimpleName();
        changeFragment(fragmentManager, fragment, tag, isAddBackStack);
    }

    /**
     * @param @param fragmentManager
     * @param @param fragment
     * @param @param clazz
     * @param @param isAddBackStack 设定文件
     * @return void 返回类型
     * @throws
     * @Title: changeFragment
     * @Description: 切换Fragment
     */
    public void changeFragment(FragmentManager fragmentManager, Fragment fragment, String tag, boolean isAddBackStack) {
        currentFragmentTag = tag;
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //fragment 替换了当前layout容器中的由com.onstar.cn.framework.R.id.fragment_container	标识的fragment.
        fragmentTransaction.replace(com.onstar.cn.framework.R.id.fragment_container, fragment, tag);
        fragmentTransaction.addToBackStack(tag);//通过调用 addToBackStack(), replace事务被保存到back stack,
        if (fragmentManager.findFragmentByTag(tag) == null) {
            log.d("Initialize fragment,add fragment to backStack");
            if (isAddBackStack) {
                fragments.add(fragment);
            }
        }
        fragmentTransaction.commitAllowingStateLoss();
    }

    /**
     * @param @param fragmentManager
     * @param @param fragment 设定文件
     * @return void 返回类型
     * @throws
     * @Title: removeFragment
     * @Description: 删除指定Fragment
     */
    public void removeFragment(FragmentManager fragmentManager, Fragment fragment) {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.remove(fragment).commitAllowingStateLoss();
    }

    /**
     * @param @param fragmentManager 设定文件
     * @return void 返回类型
     * @throws
     * @Title: removeFragment
     * @Description: 删除Stack中所有Fragment
     */
    public void removeFragment(FragmentManager fragmentManager) {
        if (CommonUtil.isNull(fragments) || fragments.size() == 0) {
            log.d("Current fragment stack is null,Don't need remove");
            return;
        }
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        for (int i = 0; i < fragments.size(); i++) {
            try {
                log.d("Remove fragment to backStack");
                fragmentManager.popBackStack();
            } catch (Exception e) {
            }
        }
        fragmentTransaction.commitAllowingStateLoss();
    }

    /**
     * @param fragmentManager
     * @param untilFragmentClazz
     * @param include
     * @author zhang kai
     * @function 找到fragment堆栈中的相应fragment，把它上面的所有fragment都pop掉
     * @comment 现在还有问题，因为addToBackStack时传的Null，所以无法正常定位到指定fragment
     */
    public void removeFragmentsUntilOne(FragmentManager fragmentManager, Class<? extends BaseFragment> untilFragmentClazz, boolean include) {
        if (CommonUtil.isNull(fragments) || fragments.size() == 0) {
            log.d("Current fragment stack is null,Don't need remove");
            return;
        }
        String tag = untilFragmentClazz.getSimpleName();
        Fragment fragment = fragmentManager.findFragmentByTag(tag);
        if (fragment == null) {
            log.d("Current fragment stack doesn't has untilFragment");
            return;
        }
        fragmentManager.popBackStackImmediate(tag, include ? FragmentManager.POP_BACK_STACK_INCLUSIVE : 0);
        int index = fragments.indexOf(fragment);
        if (index == -1) {
            return;
        }
        if (include) {
            for (int i = fragments.size() - 1; i >= index; i--) {
                fragments.remove(i);
            }
        } else {
            for (int i = fragments.size() - 1; i > index; i--) {
                fragments.remove(i);
            }
        }
    }

    /**
     * @param fragmentManager
     * @author zhang kai
     * @function 将fragment堆栈中除底部fragment之外的所有fragment都pop掉
     */
    public void removeFragmentsUntilBottom(FragmentManager fragmentManager) {
        if (CommonUtil.isNull(fragments) || fragments.size() == 0 || fragmentManager.getBackStackEntryCount() == 0) {
            log.d("Current fragment stack is null,Don't need remove");
            return;
        }
        fragmentManager.popBackStackImmediate(fragmentManager.getBackStackEntryAt(0).getId(), 0);
        for (int i = fragments.size() - 1; i > 0; i--) {
            fragments.remove(i);
        }
    }


    //    public void initShowAndHideFragments(FragmentManager fm, List<Fragment> showFragments, List<Fragment> hideFragments) {
//        FragmentTransaction fragmentTransaction = fm.beginTransaction();
//        if (showFragments != null && showFragments.size() > 0) {
//            for (Fragment showFragment : showFragments) {
//                fragmentTransaction
//                        .add(com.onstar.cn.framework.R.id.fragment_container, showFragment, showFragment.getClass().getSimpleName())
//                        .show(showFragment);
//                fragmentList.add(showFragment);
//            }
//        }
//        if (hideFragments != null && hideFragments.size() > 0) {
//            for (Fragment hideFragment : hideFragments) {
//                fragmentTransaction
//                        .add(com.onstar.cn.framework.R.id.fragment_container, hideFragment, hideFragment.getClass().getSimpleName())
//                        .hide(hideFragment);
//            }
//        }
//        fragmentTransaction.commit();
//    }
//
    private List<BaseFragment> fragmentList = new LinkedList<>();
    private List<BaseFragment> popFragmentList = new ArrayList<BaseFragment>();
    private Class prevFragment;

    public Class getPreFragment() {
        return prevFragment;
    }

    public void addFragment(FragmentManager fm, BaseFragment addFragment, boolean isAddBackStack) {
        /**
         * 若存在addfragment 则不作操作
         */
        if (fm.findFragmentByTag(addFragment.getClass().getSimpleName()) != null) {
            return;
        }
        FragmentTransaction fragmentTransaction = fm.beginTransaction();
        LogManager.getInstance().d("addFragment name tag ------------------------->>>>>" + addFragment.getClass().getSimpleName());
        fragmentTransaction.add(com.onstar.cn.framework.R.id.fragment_container, addFragment, addFragment.getClass().getSimpleName());
        fragmentTransaction.addToBackStack(addFragment.getClass().getSimpleName());//通过调用 addToBackStack(), replace事务被保存到back stack,
//        if (isAddBackStack) {
//            fragmentTransaction.addToBackStack(addFragment.getClass().getSimpleName());//通过调用 addToBackStack(), replace事务被保存到back stack,
//            popFragmentList.add(addFragment);
//        }
        fragmentList.add(addFragment);
        fragmentTransaction.commitAllowingStateLoss();
    }

    public void addFragmentWithAnimation(FragmentManager fm, BaseFragment addFragment, View view, String transName) {
        /**
         * 若存在addfragment 则不作操作
         */
        if (fm.findFragmentByTag(addFragment.getClass().getSimpleName()) != null) {
            return;
        }
        FragmentTransaction fragmentTransaction = fm.beginTransaction();
        LogManager.getInstance().d("addFragment name tag ------------------------->>>>>" + addFragment.getClass().getSimpleName());
        Slide slideTransition = new Slide(Gravity.RIGHT);
        slideTransition.setDuration(500);

        Slide exit = new Slide(Gravity.LEFT);
        exit.setDuration(500);
        ChangeBounds changeBoundsTransition = new ChangeBounds();
        changeBoundsTransition.setDuration(500);
        addFragment.setEnterTransition(slideTransition);
        addFragment.setReenterTransition(slideTransition);
        addFragment.setReturnTransition(slideTransition);
        addFragment.setSharedElementEnterTransition(changeBoundsTransition);
        addFragment.setAllowEnterTransitionOverlap(true);
        addFragment.setExitTransition(exit);
        addFragment.setAllowReturnTransitionOverlap(true);
        fragmentTransaction
                .add(com.onstar.cn.framework.R.id.fragment_container, addFragment)
                .addToBackStack(null)
                .addSharedElement(view,transName)
                .commit();
//        fragmentTransaction.addSharedElement(view, transName).add(com.onstar.cn.framework.R.id.fragment_container, addFragment, addFragment.getClass().getSimpleName());
//        fragmentTransaction.addToBackStack(addFragment.getClass().getSimpleName());//通过调用 addToBackStack(), replace事务被保存到back stack,
        fragmentList.add(addFragment);
//        fragmentTransaction.commitAllowingStateLoss();
    }

    public void showFragment(FragmentManager fm, Class showFragment, Class prevClazz) {
        if (showFragment == null) return;
        currentFragmentTag = showFragment.getSimpleName();
        if (prevClazz != null) {
            prevFragment = prevClazz;
        }
        FragmentTransaction fragmentTransaction = fm.beginTransaction();
        if (fragmentList != null && fragmentList.size() > 0) {
            for (BaseFragment baseFragment : fragmentList) {
                if (baseFragment.getClass().getSimpleName().equals(showFragment.getSimpleName())) {
                    fragmentTransaction.show(baseFragment);
                } else {
                    fragmentTransaction.hide(baseFragment);
                }
            }
        }
        fragmentTransaction.commitAllowingStateLoss();
    }

    public void showFragment(FragmentManager fm, Class showFragment, Class prevClazz,Bundle arguments) {
        if (showFragment == null) return;
        currentFragmentTag = showFragment.getSimpleName();
        if (prevClazz != null) {
            prevFragment = prevClazz;
        }
        FragmentTransaction fragmentTransaction = fm.beginTransaction();
        if (fragmentList != null && fragmentList.size() > 0) {
            for (BaseFragment baseFragment : fragmentList) {
                if (baseFragment.getClass().getSimpleName().equals(showFragment.getSimpleName())) {
                    baseFragment.setArguments(arguments);
                    fragmentTransaction.show(baseFragment);
                } else {
                    fragmentTransaction.hide(baseFragment);
                }
            }
        }
        fragmentTransaction.commitAllowingStateLoss();
    }

    public void removeUntilFragment(FragmentManager fm, Class fragmentClazz, boolean include) {
        if(fragmentClazz == null) return;
        BaseFragment destFragment = (BaseFragment) fm.findFragmentByTag(fragmentClazz.getSimpleName());
        if (destFragment != null) {
            if (fragmentList != null && fragmentList.size() > 0) {
                int index = fragmentList.indexOf(destFragment);
                if (!include) {
                    for (int i = fragmentList.size() - 1; i > index; i--) {
                        log.d("the pop up fragment is ------>" + fragmentList.get(i).getClass().getSimpleName());
                        fm.popBackStack(fragmentList.get(i).getClass().getSimpleName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
                        fragmentList.remove(i);
                    }
                } else {
                    for (int i = fragmentList.size() - 1; i >= index; i--) {
                        log.d("the pop up fragment is ------>" + fragmentList.get(i).getClass().getSimpleName());
                        fm.popBackStack(fragmentList.get(i).getClass().getSimpleName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
                        fragmentList.remove(i);
                    }
                }
            }
            showFragment(fm, fragmentClazz, destFragment.getPreFragment());
        }
    }

    public int getFragmentSize() {
        return fragmentList.size();
    }

    public void removeCurrentAndShowPrevFragment(FragmentManager fm, Class addFragment) {
        if (fragmentList != null && fragmentList.size() > 0) {
            LogManager.getInstance().d("removeCurrentAndShowPrevFragment name tag ------------------------->>>>>" + addFragment.getSimpleName());
            BaseFragment currentFragment = (BaseFragment) fm.findFragmentByTag(addFragment.getSimpleName());
            Class preFragment = currentFragment.getPreFragment();
            fragmentList.remove(currentFragment);
            fm.popBackStack(addFragment.getSimpleName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
            fm.beginTransaction().commitAllowingStateLoss();
            showFragment(fm, preFragment, prevFragment);
        }
//        BaseFragment pre = null;
//        if (fragmentList != null && fragmentList.size() > 0) {
//            FragmentTransaction fragmentTransaction = fm.beginTransaction();
//            for (BaseFragment baseFragment : fragmentList) {
//                if (baseFragment.getClass().getSimpleName().equals(addFragment.getSimpleName())) {
//                    fragmentList.remove(baseFragment);
//                    fragmentTransaction.remove(baseFragment);
//                    fm.popBackStackImmediate(addFragment.getClass().getSimpleName(), 0);
//                }
//                if (prevFragment.getSimpleName().equals(baseFragment.getClass().getSimpleName())) {
//                    pre = baseFragment.getPreFragment();
//                }
//            }
//            fragmentTransaction.commitAllowingStateLoss();
//        }
//        if (pre != null) {
//            showFragment(fm, prevFragment, pre.getClass());
//        } else {
//            showFragment(fm, prevFragment, null);
//        }
    }
}